/*
 * LamportMutex.h
 *
 *  Created on: Nov 23, 2012
 *      Author: dan
 */

#ifndef LAMPORTMUTEX_H_
#define LAMPORTMUTEX_H_

#include "Network.h"
#include "Print.hpp"

class LamportMutex {
	typedef boost::system::error_code error_code;
	enum STATE{ MTX_OUT, MTX_IN, MTX_WAIT };

public:
	LamportMutex(Network& network, Network::Team team, std::string m_name);
	virtual ~LamportMutex();

public:

	void Event_OnConnection(std::string id, error_code error);
	void Event_OnDisconnection(std::string id, error_code error);
	void Event_OnMessage(std::string id, std::string message, error_code error);

	void waitConnection();
	void waitConnection(boost::mutex::scoped_lock& ext_l);

	bool lock();
	void unlock();

private:
	bool allConnected();
	bool allReady();
	void init();
	void printTeamStatus();
	bool inTeam(std::string id);

	std::string getMutexMessage(std::string type,size_t time)const;
	bool isMutexMessage(const std::string& message)const;
	size_t getTime(const std::string& message)const;
	std::string getType(const std::string& message)const;

private:
	Network & network;
	Network::Team team;
	std::string name;
	size_t callbackId;
	typedef std::map<std::string, bool> HostList;
	typedef std::set<std::string> Team;
	HostList connected;
	HostList ready;
	Team teamSet;
	boost::mutex mtx;
	boost::condition_variable state_changed;
	size_t time;
	STATE state;
	size_t sentTime;
	std::vector<std::string> waitingList;

public:
	DebugPrint debug_print;
};

#endif /* LAMPORTMUTEX_H_ */
